package com.tyut.musicdreamer.service.music.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tyut.musicdreamer.service.music.mapper.MusicMapper;
import com.tyut.musicdreamer.service.music.mapper.UserFavoriteMusicMapper;
import com.tyut.musicdreamer.service.music.model.dto.MusicCreateRequest;
import com.tyut.musicdreamer.service.music.model.dto.MusicQueryRequest;
import com.tyut.musicdreamer.service.music.model.dto.MusicUpdateRequest;
import com.tyut.musicdreamer.service.music.model.dto.MusicUploadRequest;
import com.tyut.musicdreamer.service.music.model.entity.Music;
import com.tyut.musicdreamer.service.music.model.entity.UserFavoriteMusic;
import com.tyut.musicdreamer.service.music.model.vo.MusicVO;
import com.tyut.musicdreamer.service.music.service.MusicService;
import com.tyut.musicdreamer.service.music.service.MusicStorageService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 音乐服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MusicServiceImpl extends ServiceImpl<MusicMapper, Music> implements MusicService {

    private final MusicStorageService musicStorageService;
    private final MusicMapper musicMapper;
    private final UserFavoriteMusicMapper userFavoriteMusicMapper;

    /**
     * 上传音乐（Controller调用的方法）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public MusicVO uploadMusic(MultipartFile file, MusicCreateRequest request) {
        // 创建上传请求对象
        MusicUploadRequest uploadRequest = new MusicUploadRequest();
        uploadRequest.setFile(file);
        uploadRequest.setTitle(request.getTitle());
        uploadRequest.setDescription(request.getDescription());
        uploadRequest.setTags(request.getTags());
        uploadRequest.setStatus(1); // 默认状态为已发布
        
        return upload(uploadRequest, request.getUserId());
    }
    
    /**
     * 创建音乐（Controller调用的方法）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public MusicVO createMusic(MusicCreateRequest request) {
        // 创建音乐记录
        Music music = new Music()
                .setTitle(request.getTitle())
                .setDescription(request.getDescription())
                .setCoverUrl(null)
                .setFileUrl(null)
                .setFileType(null)
                .setFileSize(0L)
                .setDuration(0)
                .setCreatorId(request.getUserId())
                .setPlayCount(0L)
                .setLikeCount(0)
                .setFavoriteCount(0)
                .setCommentCount(0)
                .setTags(request.getTags())
                .setArtist(request.getArtist())
                .setAlbum(request.getAlbum())
                .setGenre(request.getGenre())
                .setYear(request.getYear())
                .setStatus(1) // 默认状态为已发布
                .setCreateTime(LocalDateTime.now())
                .setUpdateTime(LocalDateTime.now())
                .setDeleted(0);

        // 保存到数据库
        save(music);

        // 转换为VO并返回
        return convertToVO(music, null);
    }
    
    /**
     * 更新音乐（Controller调用的方法）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public MusicVO updateMusic(MusicUpdateRequest request) {
        // 检查音乐是否存在
        Music music = getById(request.getId());
        if (music == null) {
            throw new IllegalArgumentException("音乐不存在");
        }
        
        // 更新音乐信息
        music.setTitle(request.getTitle() != null ? request.getTitle() : music.getTitle());
        music.setDescription(request.getDescription() != null ? request.getDescription() : music.getDescription());
        music.setTags(request.getTags() != null ? request.getTags() : music.getTags());
        music.setStatus(request.getStatus() != null ? request.getStatus() : music.getStatus());
        music.setUpdateTime(LocalDateTime.now());
        
        // 保存到数据库
        updateById(music);
        
        // 转换为VO并返回
        return convertToVO(music, null);
    }
    
    /**
     * 获取音乐详情（Controller调用的方法）
     */
    @Override
    public MusicVO getMusicById(String id) {
        return getDetail(id, null);
    }
    
    /**
     * 分页查询音乐（Controller调用的方法）
     */
    @Override
    public Page<MusicVO> pageMusicList(MusicQueryRequest request) {
        return queryPage(request, null);
    }
    
    /**
     * 获取用户音乐列表（Controller调用的方法）
     */
    @Override
    public List<MusicVO> getMusicListByUserId(Long userId) {
        // 构建查询条件
        LambdaQueryWrapper<Music> wrapper = Wrappers.<Music>lambdaQuery()
                .eq(Music::getCreatorId, userId)
                .eq(Music::getDeleted, 0)
                .orderByDesc(Music::getCreateTime);
        
        // 查询列表
        List<Music> musicList = list(wrapper);
        
        // 转换为VO
        return musicList.stream()
                .map(music -> convertToVO(music, userId))
                .collect(Collectors.toList());
    }
    
    /**
     * 流式播放音乐（Controller调用的方法）
     */
    @Override
    public void streamMusic(String id, HttpServletResponse response) throws IOException {
        // 获取音乐信息
        Music music = getById(id);
        if (music == null) {
            log.error("音乐不存在，ID: {}", id);
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        
        log.info("流式播放音乐，ID: {}, 文件URL: {}", id, music.getFileUrl());
        
        // 设置响应头
        response.setContentType("audio/mpeg"); // 默认设置为MP3类型
        if (music.getFileType() != null) {
            response.setContentType(music.getFileType());
        }
        
        // 设置缓存控制
        response.setHeader("Cache-Control", "max-age=3600");
        
        try {
            // 直接获取文件输入流并传输到响应
            InputStream inputStream = musicStorageService.getFileInputStream(music.getFileUrl());
            if (inputStream == null) {
                log.error("获取文件输入流失败，ID: {}", id);
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
            
            log.info("获取文件输入流成功，开始传输数据");
            
            // 使用缓冲区传输数据
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                response.getOutputStream().write(buffer, 0, bytesRead);
            }
            response.getOutputStream().flush();
            
            // 关闭输入流
            inputStream.close();
            
            log.info("音频数据传输完成");
            
            // 更新播放次数
            play(id);
        } catch (Exception e) {
            log.error("流式播放音乐失败，ID: {}", id, e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }
    
    /**
     * 下载音乐（Controller调用的方法）
     */
    @Override
    public void downloadMusic(String id, HttpServletResponse response) throws IOException {
        // 获取音乐信息
        Music music = getById(id);
        if (music == null) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        
        // 生成包含Content-Disposition的预签名URL
        String presignedUrl;
        if (musicStorageService instanceof StorageServiceAdapter) {
            presignedUrl = ((StorageServiceAdapter)musicStorageService).generatePresignedDownloadUrl(music.getFileUrl(), 60);
        } else {
            // 使用默认方式处理，避免使用过时的实现类
            log.warn("当前存储服务不支持生成预签名URL");
            presignedUrl = musicStorageService.getFileUrl(music.getFileUrl());
        }
        
        if (presignedUrl == null) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        
        // 设置下载文件名
        response.setHeader("Content-Disposition", "attachment; filename=\"" + music.getTitle() + "\"");
        
        // 重定向到预签名URL
        response.sendRedirect(presignedUrl);
    }
    
    /**
     * 获取音乐封面（Controller调用的方法）
     */
    @Override
    public void getMusicCover(String id, HttpServletResponse response) throws IOException {
        // 获取音乐信息
        Music music = getById(id);
        if (music == null || StrUtil.isBlank(music.getCoverUrl())) {
            log.error("音乐不存在或没有封面，ID: {}", id);
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        
        log.info("获取音乐封面，ID: {}, 封面URL: {}", id, music.getCoverUrl());
        
        // 设置响应头
        response.setContentType("image/jpeg"); // 默认设置为JPEG类型
        
        // 设置缓存控制
        response.setHeader("Cache-Control", "max-age=86400"); // 封面缓存24小时
        
        try {
            // 直接获取文件输入流并传输到响应
            InputStream inputStream = musicStorageService.getFileInputStream(music.getCoverUrl());
            if (inputStream == null) {
                log.error("获取封面文件输入流失败，ID: {}", id);
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
            
            log.info("获取封面文件输入流成功，开始传输数据");
            
            // 使用缓冲区传输数据
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                response.getOutputStream().write(buffer, 0, bytesRead);
            }
            response.getOutputStream().flush();
            
            // 关闭输入流
            inputStream.close();
            
            log.info("封面数据传输完成");
        } catch (Exception e) {
            log.error("获取音乐封面失败，ID: {}", id, e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 上传音乐封面（Controller调用的方法）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadMusicCover(String id, MultipartFile file, Long userId) throws IOException {
        log.info("开始上传音乐封面，音乐ID: {}, 用户ID: {}, 文件名: {}, 文件类型: {}, 文件大小: {}", 
                id, userId, file.getOriginalFilename(), file.getContentType(), file.getSize());
        
        // 检查音乐是否存在
        Music music = getById(id);
        if (music == null) {
            log.error("音乐不存在，ID: {}", id);
            throw new IllegalArgumentException("音乐不存在");
        }
        
        // 检查是否有权限修改
        if (!Objects.equals(music.getCreatorId(), userId)) {
            log.warn("用户[{}]尝试上传音乐[{}]的封面，但无权限", userId, id);
            throw new IllegalArgumentException("无权限修改该音乐");
        }
        
        // 检查封面文件
        if (file == null || file.isEmpty()) {
            log.error("封面文件为空，音乐ID: {}", id);
            throw new IllegalArgumentException("封面文件不能为空");
        }
        
        // 检查文件类型
        String contentType = file.getContentType();
        if (contentType == null || !contentType.startsWith("image/")) {
            log.error("封面文件类型不正确，音乐ID: {}, 文件类型: {}", id, contentType);
            throw new IllegalArgumentException("只能上传图片文件");
        }
        
        try {
            // 打印文件详细信息
            log.info("封面文件详情 - 文件名: {}, 原始文件名: {}, 内容类型: {}, 大小: {} 字节", 
                file.getName(), file.getOriginalFilename(), file.getContentType(), file.getSize());
            
            // 检查文件是否可读
            if (!file.isEmpty()) {
                log.info("封面文件非空，大小: {} 字节", file.getSize());
                
                // 尝试读取文件内容
                try {
                    byte[] fileContent = file.getBytes();
                    log.info("成功读取封面文件内容，大小: {} 字节", fileContent.length);
                } catch (IOException e) {
                    log.error("读取封面文件内容失败", e);
                    throw new IOException("读取封面文件内容失败", e);
                }
            } else {
                log.error("封面文件为空，无法处理");
                throw new IllegalArgumentException("封面文件为空");
            }
            
            // 存储封面图片
            log.info("开始存储封面图片，音乐ID: {}", id);
            String coverUrl = null;
            try {
                coverUrl = musicStorageService.storeCover(file);
                log.info("封面图片存储成功，音乐ID: {}, 封面URL: {}", id, coverUrl);
            } catch (Exception e) {
                log.error("存储封面图片失败", e);
                throw new IOException("存储封面图片失败", e);
            }
            
            if (coverUrl == null || coverUrl.isEmpty()) {
                log.error("存储封面图片后返回的URL为空");
                throw new IOException("存储封面图片失败，返回的URL为空");
            }
            
            // 如果原来有封面，则删除原封面
            if (StrUtil.isNotBlank(music.getCoverUrl())) {
                try {
                    log.info("删除原封面，音乐ID: {}, 原封面URL: {}", id, music.getCoverUrl());
                    musicStorageService.delete(music.getCoverUrl());
                } catch (Exception e) {
                    log.warn("删除原封面失败，音乐ID: {}, 原封面URL: {}", id, music.getCoverUrl(), e);
                }
            }
            
            // 更新音乐记录
            music.setCoverUrl(coverUrl);
            music.setUpdateTime(LocalDateTime.now());
            boolean updated = updateById(music);
            log.info("更新音乐封面记录结果: {}, 音乐ID: {}, 封面URL: {}", updated, id, coverUrl);
            
            if (!updated) {
                log.error("更新音乐封面记录失败，音乐ID: {}", id);
                throw new RuntimeException("更新音乐封面记录失败");
            }
        } catch (Exception e) {
            log.error("上传音乐封面失败，音乐ID: {}, 错误: {}", id, e.getMessage(), e);
            throw e;
        }
        
        log.info("音乐封面上传成功，音乐ID: {}, 用户ID: {}", id, userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MusicVO upload(MusicUploadRequest request, Long userId) {
        // 上传音乐文件
        MultipartFile musicFile = request.getFile();
        if (musicFile == null || musicFile.isEmpty()) {
            throw new IllegalArgumentException("音乐文件不能为空");
        }
        
        log.info("开始上传音乐文件: 文件名={}, 内容类型={}, 大小={}字节", 
            musicFile.getOriginalFilename(), musicFile.getContentType(), musicFile.getSize());

        // 存储音乐文件
        try {
            String musicFileUrl = musicStorageService.store(musicFile);
            log.info("音乐文件上传成功: URL={}", musicFileUrl);
            
            // 获取音频时长
            Integer duration = 0;
            Path tempFile = null;
            try {
                // 创建临时文件
                String extension = FileUtil.extName(musicFile.getOriginalFilename());
                tempFile = Files.createTempFile("music_", "." + extension);
                musicFile.transferTo(tempFile.toFile());
                
                // 读取音频信息
                AudioFile audioFile = AudioFileIO.read(tempFile.toFile());
                duration = audioFile.getAudioHeader().getTrackLength();
                log.info("成功读取音频时长: {}秒", duration);
            } catch (Exception e) {
                log.error("获取音频时长失败: {}", e.getMessage(), e);
            } finally {
                // 确保临时文件被删除
                if (tempFile != null) {
                    try {
                        Files.deleteIfExists(tempFile);
                    } catch (IOException e) {
                        log.warn("删除临时文件失败", e);
                    }
                }
            }

            // 上传封面图片
            String coverUrl = null;
            if (request.getCover() != null && !request.getCover().isEmpty()) {
                log.info("开始上传封面图片: 文件名={}, 内容类型={}, 大小={}字节", 
                    request.getCover().getOriginalFilename(), 
                    request.getCover().getContentType(), 
                    request.getCover().getSize());
                    
                coverUrl = musicStorageService.storeCover(request.getCover());
                log.info("封面图片上传成功: URL={}", coverUrl);
            }

            // 创建音乐记录
            Music music = new Music()
                    .setTitle(request.getTitle())
                    .setDescription(request.getDescription())
                    .setCoverUrl(coverUrl)
                    .setFileUrl(musicFileUrl)
                    .setFileType(musicFile.getContentType())
                    .setFileSize(musicFile.getSize())
                    .setDuration(duration)
                    .setCreatorId(userId)
                    .setPlayCount(0L)
                    .setLikeCount(0)
                    .setFavoriteCount(0)
                    .setCommentCount(0)
                    .setTags(request.getTags())
                    .setStatus(request.getStatus())
                    .setCreateTime(LocalDateTime.now())
                    .setUpdateTime(LocalDateTime.now())
                    .setDeleted(0);

            // 保存到数据库
            save(music);
            log.info("音乐记录保存成功: ID={}, 标题={}", music.getId(), music.getTitle());

            // 转换为VO并返回
            return convertToVO(music, null);
        } catch (Exception e) {
            log.error("音乐上传失败: {}", e.getMessage(), e);
            throw e;
        }
    }

    @Override
    public MusicVO getDetail(String id, Long userId) {
        log.info("获取音乐详情，ID: {}, 用户ID: {}", id, userId);
        
        if (id == null) {
            log.error("音乐ID为空");
            throw new IllegalArgumentException("音乐ID不能为空");
        }
        
        Music music = getById(id);
        if (music == null) {
            log.error("音乐不存在，ID: {}", id);
            throw new IllegalArgumentException("音乐不存在，ID: " + id);
        }
        
        if (music.getDeleted() == 1) {
            log.error("音乐已被删除，ID: {}", id);
            throw new IllegalArgumentException("音乐已被删除");
        }
        
        log.info("音乐详情获取成功，ID: {}, 标题: {}", id, music.getTitle());
        return convertToVO(music, userId);
    }

    @Override
    public Page<MusicVO> queryPage(MusicQueryRequest request, Long userId) {
        // 构建查询条件
        LambdaQueryWrapper<Music> wrapper = Wrappers.<Music>lambdaQuery()
                .eq(Music::getStatus, 1) // 只查询已发布的
                .eq(Music::getDeleted, 0); // 未删除的
        
        // 关键词搜索
        if (StrUtil.isNotBlank(request.getKeyword())) {
            wrapper.and(w -> w
                    .like(Music::getTitle, request.getKeyword())
                    .or()
                    .like(Music::getDescription, request.getKeyword())
            );
        }
        
        // 标签筛选
        if (StrUtil.isNotBlank(request.getTag())) {
            wrapper.like(Music::getTags, request.getTag());
        }
        
        // 创作者筛选
        if (request.getCreatorId() != null) {
            wrapper.eq(Music::getCreatorId, request.getCreatorId());
        }
        
        // 排序
        String orderBy = "create_time";
        if (StrUtil.isNotBlank(request.getOrderBy())) {
            orderBy = request.getOrderBy();
        }
        
        boolean isAsc = "asc".equalsIgnoreCase(request.getOrderType());
        
        switch (orderBy) {
            case "play_count":
                wrapper.orderBy(true, isAsc, Music::getPlayCount);
                break;
            case "like_count":
                wrapper.orderBy(true, isAsc, Music::getLikeCount);
                break;
            case "favorite_count":
                wrapper.orderBy(true, isAsc, Music::getFavoriteCount);
                break;
            case "create_time":
            default:
                wrapper.orderBy(true, isAsc, Music::getCreateTime);
                break;
        }
        
        // 分页查询
        Page<Music> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<Music> musicPage = page(page, wrapper);
        
        // 转换为VO
        Page<MusicVO> voPage = new Page<>(musicPage.getCurrent(), musicPage.getSize(), musicPage.getTotal());
        List<MusicVO> voList = musicPage.getRecords().stream()
                .map(music -> convertToVO(music, userId))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    public boolean play(String id) {
        return musicMapper.incrementPlayCount(id) > 0;
    }

    @Override
    public boolean like(String id, Long userId) {
        // 这里应该有一个点赞记录表，暂时只增加计数
        return musicMapper.incrementLikeCount(id) > 0;
    }

    @Override
    public boolean cancelLike(String id, Long userId) {
        // 这里应该有一个点赞记录表，暂时只减少计数
        return musicMapper.decrementLikeCount(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean favorite(String id, Long userId) {
        log.info("收藏音乐，音乐ID: {}, 用户ID: {}", id, userId);
        
        // 检查音乐是否存在
        Music music = getById(id);
        if (music == null) {
            log.error("音乐不存在，ID: {}", id);
            throw new IllegalArgumentException("音乐不存在，ID: " + id);
        }
        
        // 检查是否已收藏
        int count = userFavoriteMusicMapper.checkFavorite(userId, id);
        if (count > 0) {
            log.info("用户已收藏该音乐，无需重复收藏");
            return true;
        }
        
        // 创建收藏关系
        UserFavoriteMusic favorite = new UserFavoriteMusic()
                .setUserId(userId)
                .setMusicId(id)
                .setCreateTime(LocalDateTime.now());
        
        // 保存收藏关系
        boolean success = userFavoriteMusicMapper.insert(favorite) > 0;
        
        // 增加音乐收藏计数
        if (success) {
            musicMapper.incrementFavoriteCount(id);
            log.info("收藏音乐成功");
        }
        
        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelFavorite(String id, Long userId) {
        log.info("取消收藏音乐，音乐ID: {}, 用户ID: {}", id, userId);
        
        // 检查是否已收藏
        int count = userFavoriteMusicMapper.checkFavorite(userId, id);
        if (count == 0) {
            log.info("用户未收藏该音乐，无需取消");
            return true;
        }
        
        // 构建查询条件
        LambdaQueryWrapper<UserFavoriteMusic> wrapper = Wrappers.<UserFavoriteMusic>lambdaQuery()
                .eq(UserFavoriteMusic::getUserId, userId)
                .eq(UserFavoriteMusic::getMusicId, id);
        
        // 删除收藏关系
        boolean success = userFavoriteMusicMapper.delete(wrapper) > 0;
        
        // 减少音乐收藏计数
        if (success) {
            musicMapper.decrementFavoriteCount(id);
            log.info("取消收藏音乐成功");
        }
        
        return success;
    }

    /**
     * 查询用户收藏的音乐列表
     */
    @Override
    public Page<MusicVO> queryFavoriteMusics(MusicQueryRequest request, Long userId, List<String> favoriteIds) {
        log.info("查询用户收藏的音乐列表，用户ID: {}, 收藏数量: {}", userId, favoriteIds.size());
        
        // 构建查询条件
        LambdaQueryWrapper<Music> wrapper = Wrappers.<Music>lambdaQuery()
                .in(Music::getId, favoriteIds)
                .eq(Music::getStatus, 1) // 只查询已发布的
                .eq(Music::getDeleted, 0); // 未删除的
        
        // 排序
        String orderBy = request.getOrderBy();
        boolean isAsc = "asc".equalsIgnoreCase(request.getOrderType());
        
        switch (orderBy) {
            case "play_count":
                wrapper.orderBy(true, isAsc, Music::getPlayCount);
                break;
            case "like_count":
                wrapper.orderBy(true, isAsc, Music::getLikeCount);
                break;
            case "favorite_count":
                wrapper.orderBy(true, isAsc, Music::getFavoriteCount);
                break;
            case "create_time":
            default:
                wrapper.orderBy(true, isAsc, Music::getCreateTime);
                break;
        }
        
        // 分页查询
        Page<Music> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<Music> musicPage = page(page, wrapper);
        
        // 转换为VO
        Page<MusicVO> voPage = new Page<>(musicPage.getCurrent(), musicPage.getSize(), musicPage.getTotal());
        List<MusicVO> voList = musicPage.getRecords().stream()
                .map(music -> convertToVO(music, userId))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteMusic(String id, Long userId) {
        // 检查是否是创作者
        Music music = getById(id);
        if (music == null) {
            throw new IllegalArgumentException("音乐不存在");
        }
        
        if (!Objects.equals(music.getCreatorId(), userId)) {
            throw new IllegalArgumentException("无权删除该音乐");
        }
        
        // 删除音乐文件
        if (StrUtil.isNotBlank(music.getFileUrl())) {
            musicStorageService.delete(music.getFileUrl());
        }
        
        // 删除封面图片
        if (StrUtil.isNotBlank(music.getCoverUrl())) {
            musicStorageService.delete(music.getCoverUrl());
        }
        
        // 逻辑删除记录
        return removeById(id);
    }

    /**
     * 获取随机音乐列表
     *
     * @param count 获取数量
     * @param userId 用户ID
     * @return 音乐列表
     */
    @Override
    public List<MusicVO> getRandomMusic(Integer count, Long userId) {
        // 设置默认获取数量，最大不超过50首
        int limit = count == null || count <= 0 ? 10 : Math.min(count, 50);
        
        log.info("获取随机音乐列表: count={}, userId={}", limit, userId);
        
        try {
            // 查询已发布的音乐
            LambdaQueryWrapper<Music> queryWrapper = Wrappers.<Music>lambdaQuery()
                .eq(Music::getStatus, 1) // 状态为已发布
                .eq(Music::getDeleted, 0) // 未删除
                .isNotNull(Music::getFileUrl) // 必须有音乐文件
                .orderByDesc(Music::getPlayCount); // 按播放次数排序
            
            // 获取总数
            long total = count(queryWrapper);
            if (total == 0) {
                log.warn("没有可用的音乐");
                return Collections.emptyList();
            }
            
            // 生成随机偏移量，最多从总数-limit开始
            long maxOffset = Math.max(0, total - limit);
            long randomOffset = maxOffset > 0 ? new Random().nextLong(maxOffset) : 0;
            
            // 查询随机音乐
            Page<Music> page = new Page<>(randomOffset / limit + 1, limit);
            page = page(page, queryWrapper);
            
            // 转换为VO
            return page.getRecords().stream()
                .map(music -> convertToVO(music, userId))
                .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("获取随机音乐列表失败", e);
            return Collections.emptyList();
        }
    }

    /**
     * 将实体转换为VO
     */
    private MusicVO convertToVO(Music music, Long userId) {
        MusicVO vo = new MusicVO()
                .setId(music.getId())
                .setTitle(music.getTitle())
                .setDescription(music.getDescription())
                .setCoverUrl(StrUtil.isNotBlank(music.getCoverUrl()) ? musicStorageService.getFileUrl(music.getCoverUrl()) : null)
                .setFileUrl(musicStorageService.getFileUrl(music.getFileUrl()))
                .setFileType(music.getFileType())
                .setFileSize(music.getFileSize())
                .setDuration(music.getDuration())
                .setCreatorId(music.getCreatorId())
                .setPlayCount(music.getPlayCount())
                .setLikeCount(music.getLikeCount())
                .setFavoriteCount(music.getFavoriteCount())
                .setCommentCount(music.getCommentCount())
                .setTags(music.getTags())
                .setStatus(music.getStatus())
                .setCreateTime(music.getCreateTime())
                .setUpdateTime(music.getUpdateTime());
        
        // 处理标签
        if (StrUtil.isNotBlank(music.getTags())) {
            vo.setTagArray(music.getTags().split(","));
        } else {
            vo.setTagArray(new String[0]);
        }
        
        // 设置默认的创作者信息
        vo.setCreatorName("用户" + music.getCreatorId());
        vo.setCreatorAvatar("https://api.dicebear.com/7.x/avataaars/svg?seed=user" + music.getCreatorId());
        
        // 查询用户是否已收藏该音乐
        if (userId != null) {
            int favoriteCount = userFavoriteMusicMapper.checkFavorite(userId, music.getId());
            vo.setFavorited(favoriteCount > 0);
            
            // TODO: 从点赞记录表中查询是否已点赞
            vo.setLiked(false);
        } else {
            vo.setFavorited(false);
            vo.setLiked(false);
        }
        
        return vo;
    }

    @Override
    public String getPresignedUrl(String objectKey, Integer expirationMinutes) {
        log.info("生成预签名URL, 对象键: {}, 过期时间: {}分钟", objectKey, expirationMinutes);
        
        if (objectKey == null || objectKey.trim().isEmpty()) {
            return null;
        }
        
        try {
            // 委托给musicStorageService生成预签名URL
            // 我们应该使用StorageServiceAdapter而不是过时的AliyunOssMusicStorageServiceImpl
            if (musicStorageService instanceof StorageServiceAdapter storageAdapter) {
                return storageAdapter.generatePresignedUrl(objectKey, expirationMinutes);
            } else {
                log.warn("当前存储服务不支持生成预签名URL");
                return objectKey; // 如果不支持，则直接返回原始对象键
            }
        } catch (Exception e) {
            log.error("生成预签名URL失败", e);
            return objectKey;
        }
    }

    @Override
    public boolean recordPlay(String id, Long userId) {
        return play(id);
    }

    @Override
    public boolean likeMusic(String id, Long userId) {
        return like(id, userId);
    }

    @Override
    public boolean unlikeMusic(String id, Long userId) {
        return cancelLike(id, userId);
    }

    @Override
    public boolean favoriteMusic(String id, Long userId) {
        log.info("收藏音乐，音乐ID: {}, 用户ID: {}", id, userId);
        try {
            return favorite(id, userId);
        } catch (Exception e) {
            log.error("收藏音乐失败", e);
            return false;
        }
    }

    @Override
    public boolean unfavoriteMusic(String id, Long userId) {
        log.info("取消收藏音乐，音乐ID: {}, 用户ID: {}", id, userId);
        try {
            return cancelFavorite(id, userId);
        } catch (Exception e) {
            log.error("取消收藏音乐失败", e);
            return false;
        }
    }

    @Override
    public Page<MusicVO> getUserFavorites(Long userId, Integer pageNum, Integer pageSize) {
        log.info("获取用户收藏的音乐列表，用户ID: {}, 页码: {}, 每页数量: {}", userId, pageNum, pageSize);
        
        try {
            // 查询用户收藏的音乐ID列表
            LambdaQueryWrapper<UserFavoriteMusic> favoriteWrapper = Wrappers.<UserFavoriteMusic>lambdaQuery()
                    .eq(UserFavoriteMusic::getUserId, userId)
                    .orderByDesc(UserFavoriteMusic::getCreateTime);
            
            // 分页查询收藏记录
            Page<UserFavoriteMusic> favoritePage = new Page<>(pageNum, pageSize);
            Page<UserFavoriteMusic> favoriteResult = userFavoriteMusicMapper.selectPage(favoritePage, favoriteWrapper);
            
            // 提取音乐ID列表
            List<String> musicIds = favoriteResult.getRecords().stream()
                    .map(UserFavoriteMusic::getMusicId)
                    .collect(Collectors.toList());
            
            if (musicIds.isEmpty()) {
                // 如果没有收藏记录，返回空结果
                Page<MusicVO> emptyPage = new Page<>(pageNum, pageSize, 0);
                emptyPage.setRecords(Collections.emptyList());
                return emptyPage;
            }
            
            // 查询音乐详情
            LambdaQueryWrapper<Music> musicWrapper = Wrappers.<Music>lambdaQuery()
                    .in(Music::getId, musicIds)
                    .eq(Music::getDeleted, 0);
            
            List<Music> musicList = list(musicWrapper);
            
            // 按照收藏顺序排序
            Map<String, Integer> idOrderMap = new HashMap<>();
            for (int i = 0; i < musicIds.size(); i++) {
                idOrderMap.put(musicIds.get(i), i);
            }
            
            List<Music> orderedMusicList = musicList.stream()
                    .sorted(Comparator.comparingInt(m -> idOrderMap.getOrDefault(m.getId(), Integer.MAX_VALUE)))
                    .collect(Collectors.toList());
            
            // 转换为VO
            List<MusicVO> voList = orderedMusicList.stream()
                    .map(music -> convertToVO(music, userId))
                    .collect(Collectors.toList());
            
            // 构建结果页
            Page<MusicVO> resultPage = new Page<>(pageNum, pageSize, favoriteResult.getTotal());
            resultPage.setRecords(voList);
            
            return resultPage;
        } catch (Exception e) {
            log.error("获取用户收藏音乐列表失败", e);
            throw new RuntimeException("获取收藏列表失败", e);
        }
    }
} 
